package com.ymxk.timestar.view.smritimap;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.ymxk.timestar.smritimap.R;
import com.ymxk.timestar.view.smritimap.pop.BasePopup;
import com.ymxk.timestar.view.smritimap.pop.EasyPopup;
import com.ymxk.timestar.view.smritimap.pop.XGravity;
import com.ymxk.timestar.view.smritimap.pop.YGravity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class SmritiMapView extends View implements DrawableDrawing {

    private final String TAG = this.getClass().getSimpleName();

    //定义默认的高度
    private final int defaultStepIndicatorNum
            = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
            100,
            getResources().getDisplayMetrics());
    /**
     * 主要传承星球图标的半径
     */
    private float mStarRadius;
    /**
     * 该View的X轴的中间位置
     */
    private float mCenterX;
    //该View的Y轴的中间位置
    private float mCenterY;
    private int mSmritiNum = 0;//当前有几部流程    there are currently few step
    /**
     * 两个星球之间的间距
     */
    private float mLinePadding;

    private List<Float> mCircleCenterPointPositionList;//定义所有圆的圆心点位置的集合
    private Paint mArrowPaint;
    private Paint mDottedArrowPaint;//完成paint      definition mCompletedPaint
    private int mArrowColor = ContextCompat.getColor(getContext(), R.color.color_arrow);
    private PathEffect mEffects;
    private Path mVerticalArrowPath;
    private Path mCornerArrowPath;
    private int mHeight;//这个控件的动态高度    this view dynamic height
    private boolean mIsReverseDraw;//is reverse draw this view;
    private final List<SmritiEntity> mSmritiEntityList = new ArrayList<>();
    private Paint mTextPaint;
    private int mTextColor = Color.parseColor("#FFFFFF");
    private int mSelfTextColor = Color.parseColor("#19FFEB");
    private float mTextSize;
    private float textTopMargin;
    /**
     * 箭头粗细
     */
    private float mArrowStrokeWidth;

    /**
     * 箭头的2个边的长度
     */
    private float mArrowLineLength = 50;

    /**
     * 箭头顶部距离文字底部之间的距离
     */
    private float mArrowTopMargin = 30;
    /**
     * 箭头底部距离图片之间的距离
     */
    private float mArrowBottomMargin;
    private float mCornerLineLength;
    private float mCornerRadius;
    private float mBranchIconRadius;
    private long mDownTime;
    private SmritiEntity mClickSmritiEntity;
    private boolean scrollToBottom;

    public SmritiMapView(Context context) {
        this(context, null);
    }

    public SmritiMapView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SmritiMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
        initAttr(context, attrs, defStyle);
        initTextPaint();
        initArrowPaint();
        onInitCornerArrowPaint();
        setOnClickListener(this::onSmritiMapViewClick);
        initBottomPop();
    }

    private void onSmritiMapViewClick(View view) {


    }

    private void initAttr(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SmritiMapView, defStyleAttr, 0);
        //mColor = array.getColor(R.styleable.BackArrowView_bav_color, Color.argb(255, 0, 0, 0));
        mArrowStrokeWidth = array.getDimension(R.styleable.SmritiMapView_arrow_stroke_width, dpToPx(1.0f));
        array.recycle();
    }

    private void initArrowPaint() {
        mArrowPaint = new Paint();
        mArrowPaint.setAntiAlias(true);
        mArrowPaint.setColor(mArrowColor);
        mArrowPaint.setStyle(Paint.Style.STROKE);
        mArrowPaint.setStrokeWidth(mArrowStrokeWidth);
        mArrowPaint.setStrokeJoin(Paint.Join.ROUND);
    }

    private void initTextPaint() {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setColor(mTextColor);
    }

    /**
     * init
     */
    private void init() {
        mCornerRadius = dpToPx(20);
        mCornerLineLength = dpToPx(100);
        mArrowBottomMargin = dpToPx(10);
        mArrowTopMargin = dpToPx(10);
        mArrowLineLength = dpToPx(6);
        textTopMargin = dpToPx(0);
        mTextSize = dpToPx(8);
        mVerticalArrowPath = new Path();
        mCornerArrowPath = new Path();
        mEffects = new DashPathEffect(new float[]{8, 8, 8, 8}, 1);
        mCircleCenterPointPositionList = new ArrayList<>();//初始化
        //圆的半径  set mCircleRadius
        mStarRadius = 0.28f * defaultStepIndicatorNum;
        mBranchIconRadius = 0.27f * defaultStepIndicatorNum;
        //线与线之间的间距    set mLinePadding
        mLinePadding = 0.85f * defaultStepIndicatorNum;
        mIsReverseDraw = false;
    }

    private void onInitCornerArrowPaint() {
        mDottedArrowPaint = new Paint();
        mDottedArrowPaint.setAntiAlias(true);
        mDottedArrowPaint.setColor(mArrowColor);
        mDottedArrowPaint.setStyle(Paint.Style.STROKE);
        mDottedArrowPaint.setStrokeWidth(mArrowStrokeWidth);
        mDottedArrowPaint.setPathEffect(mEffects);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.i(TAG, "onMeasure");
        int width = (int) (mStarRadius * 2 + mCornerLineLength * 2 + mArrowLineLength * 10 + getPaddingLeft() + getRight());


        mHeight = 0;
        if (mSmritiNum > 0) {
            mHeight = (int) ((mStarRadius * 2 + textTopMargin + mTextSize) * mSmritiNum
                    + (mSmritiNum - 1) * mLinePadding);
            mCenterY = (float) mHeight / 2;

            /*mHeight = (int) (getPaddingTop()
                    + getPaddingBottom()
                    + (mStarRadius * 2 + textTopMargin + mTextSize) * mSmritiNum
                    + (mSmritiNum - 1) * mLinePadding);*/
        }

        onSetupPadding();
        Log.i(TAG, "onMeasure--->MeasureSpec:" + MeasureSpec.getMode(widthMeasureSpec));
//        if (MeasureSpec.UNSPECIFIED != MeasureSpec.getMode(widthMeasureSpec)) {
//            width = Math.min(width, MeasureSpec.getSize(widthMeasureSpec));
//        }
        Log.i(TAG, "onMeasure--->width:" + width);
        mHeight = mHeight + getPaddingTop() + getPaddingBottom();
        setMeasuredDimension(width, mHeight);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.i(TAG, "onSizeChanged");
        mCenterX = (float) getWidth() / 2;
        for (int i = 0; i < mSmritiNum; i++) {
            if (mIsReverseDraw) {
                mCircleCenterPointPositionList.add(mHeight - (mStarRadius + i * mStarRadius * 2 + i * mLinePadding));
            } else {
                mCircleCenterPointPositionList.add(getPaddingTop()
                        + mStarRadius
                        + i * mStarRadius * 2
                        + i * mLinePadding);
            }
        }

    }

    private void onSetupPadding() {
        float selfY = (int) (mStarRadius + mSelfPosition * mStarRadius * 2 + mSelfPosition * mLinePadding);
        if (selfY < mCenterY) {
            int top = (int) (mCenterY - selfY);
            setPadding(0, top, 0, 0);
        } else if (selfY > mCenterY) {
            //
            int bottom = (int) (selfY - mCenterY);
            setPadding(0, 0, 0, bottom);
            scrollToBottom = true;
        }
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        Log.i(TAG, "onDraw");
        int selfIndex = -1;
        for (int i = 0; i < mCircleCenterPointPositionList.size(); i++) {

            final float pointY
                    = mCircleCenterPointPositionList.get(i);

            int starLeft = (int) (mCenterX - mStarRadius);
            Rect rect
                    = new Rect(starLeft,
                    (int) (pointY - mStarRadius),
                    (int) (mCenterX + mStarRadius),
                    (int) (pointY + mStarRadius));

            SmritiEntity smritiEntity
                    = mSmritiEntityList.get(i);
            if (smritiEntity.isSelf()) {
                selfIndex = i;
                smritiEntity.setGrade(1);
            } else {
                smritiEntity.setGrade(selfIndex == -1 ? 1 : 4);
            }
            onDrawSmritiStarIcon(canvas, smritiEntity, rect);

            float textY = rect.bottom + mTextSize + textTopMargin;
            String name
                    = smritiEntity.isSelf()
                    ? smritiEntity.getStarName().concat("(我)")
                    : smritiEntity.getStarName();
            mTextPaint.setColor(smritiEntity.isSelf() ? mSelfTextColor : mTextColor);
            onDrawSmritiStarName(canvas, name, mCenterX, textY);
            mTextPaint.setColor(mTextColor);
            if (i < mCircleCenterPointPositionList.size() - 1) {
                final float nextYPoint = mCircleCenterPointPositionList.get(i + 1);
                float startX = mCenterX;
                float startY = textY + mArrowTopMargin;
                float endX = mCenterX;
                float endY = nextYPoint - mStarRadius * 1 - mArrowBottomMargin;

                onDrawSmritiStarArrow(canvas, startX, startY, endX, endY);

                float connerStartX = i % 2 == 0 ? mCenterX - mStarRadius : mCenterX + mStarRadius;
                float connerCenterX = i % 2 == 0 ? connerStartX - mCornerLineLength : connerStartX + mCornerLineLength;
                float connerEndY = pointY + mCornerLineLength + 0;

                //绘制辅继承人节点、
                SmritiEntity lesserChild = smritiEntity.lesserChild();
                if (lesserChild != null) {
                    if (smritiEntity.isSelfParent()) {
                        lesserChild.setGrade(3);
                    } else {
                        lesserChild.setGrade(4);
                    }
                    Rect branchRect = new Rect((int) (connerCenterX - mBranchIconRadius),
                            (int) (nextYPoint - mBranchIconRadius),
                            (int) (connerCenterX + mBranchIconRadius),
                            (int) (nextYPoint + mBranchIconRadius));
                    float childX = branchRect.centerX();
                    float childY = branchRect.bottom + mTextSize + textTopMargin;
                    if (i % 2 == 0) {
                        /*onDrawBranchIcon(canvas,
                                lesserChild.getStarIconId(),
                                branchRect);*/
                        lesserChild.setNodeType(SmritiEntity.NODE_LEFT);
                        onDrawSmritiStarIcon(canvas, lesserChild, branchRect);
                        onDrawSmritiStarName(canvas, lesserChild.getStarName(), childX, childY);
                        onDrawLeftCornerArrow(canvas,
                                connerStartX, pointY,
                                connerCenterX, pointY,
                                connerCenterX, connerEndY);
                    } else {
                        /*onDrawBranchIcon(canvas,
                                lesserChild.getStarIconId(),
                                branchRect);*/
                        lesserChild.setNodeType(SmritiEntity.NODE_RIGHT);
                        onDrawSmritiStarIcon(canvas, lesserChild, branchRect);
                        onDrawSmritiStarName(canvas, lesserChild.getStarName(), childX, childY);
                        onDrawRightCornerArrow(canvas,
                                connerStartX, pointY,
                                connerCenterX, pointY,
                                connerCenterX, connerEndY);
                    }
                }

                //绘制辅父传承人节点、
                SmritiEntity lesserParent = smritiEntity.lesserParent();
                if (lesserParent != null) {
                    if (smritiEntity.isSelf()) {
                        lesserParent.setGrade(2);
                    }
                    lesserParent.setNodeType(SmritiEntity.NODE_LEFT_TOP);
                    int left = (int) (connerCenterX + (mCenterX - connerCenterX) / 4 - mStarRadius);
                    int top = (int) (pointY - mStarRadius - mArrowBottomMargin - mLinePadding / 2);
                    int right = (int) (left + mStarRadius * 2);
                    int bottom = (int) (top + mStarRadius * 2);
                    Rect lesserParentRect = new Rect(left,
                            top,
                            right,
                            bottom);
                    onDrawSmritiStarIcon(canvas, lesserParent, lesserParentRect);
                    float parentY = bottom + mTextSize + textTopMargin;
                    //float parentY = bottom + mTextSize;
                    onDrawSmritiStarName(canvas, lesserParent.getStarName(), lesserParentRect.centerX(), parentY);
                    //onDrawLesserSmritiStarArrow(canvas, startX, startY, endX, endY);
                    float r = 75;
                    RectF oval = new RectF();
                    oval.left = right - r;
                    oval.top = lesserParentRect.centerY();
                    //oval.right = right + r;
                    oval.right = starLeft;
                    oval.bottom = lesserParentRect.centerY() + r;
                    //onDrawLesserSmritiStarArrow(canvas, oval);
                    onDrawArcAngleArrowByCanvas(canvas, oval);
                }
            }
        }
    }

    private void onDrawArcAngleArrowByCanvas(Canvas canvas, RectF oval) {
        //Canvas arcCanvas = new Canvas();
        canvas.save();
        canvas.drawArc(oval, -90, 90, false, mDottedArrowPaint);
        float endX = oval.right;
        float endY = oval.centerY();
        float arrowLength = 20;
        canvas.drawLine(endX, endY, endX - arrowLength, endY - arrowLength / 2, mDottedArrowPaint);
        canvas.drawLine(endX, endY, endX + arrowLength / 2, endY - arrowLength, mDottedArrowPaint);
        canvas.restore();
    }

    /**
     * 绘制辅传承人节点的箭头、
     *
     * @param canvas 画布
     */
    private void onDrawLesserSmritiStarArrow(Canvas canvas, RectF oval) {
        Path path = new Path();
        path.reset();
        path.arcTo(oval, -90, 90);

        float endX = oval.right;
        float endY = oval.centerY();

        float arrowLength = 20;
        path.moveTo(endX, endY);
        path.lineTo(endX - arrowLength, endY - arrowLength);

        path.moveTo(endX, endY);
        path.lineTo(endX + arrowLength, endY - arrowLength);
        path.close();
        canvas.drawPath(path, mDottedArrowPaint);
    }

    private void onDrawBranchIcon(Canvas canvas, int resId, Rect bounds) {
        Drawable drawable = ContextCompat.getDrawable(getContext(), resId);
        if (null != drawable) {
            drawable.setBounds(bounds);
            drawable.draw(canvas);
        }
    }

    private void onDrawRightCornerArrow(Canvas canvas, float startX, float startY, float centerX, float centerY, float endX, float endY) {
        mCornerArrowPath.reset();

        mCornerArrowPath.moveTo(startX, startY);
        mCornerArrowPath.lineTo(centerX - mCornerRadius, centerY);

        mCornerArrowPath.quadTo(centerX, centerY, centerX, centerY + mCornerRadius);
        mCornerArrowPath.moveTo(centerX, centerY + mCornerRadius);
        mCornerArrowPath.lineTo(endX, endY);

        mCornerArrowPath.moveTo(endX, endY);
        mCornerArrowPath.lineTo(endX - mArrowLineLength, endY - mArrowLineLength);

        mCornerArrowPath.moveTo(endX, endY);
        mCornerArrowPath.lineTo(endX + mArrowLineLength, endY - mArrowLineLength);

        mCornerArrowPath.close();
        canvas.drawPath(mCornerArrowPath, mDottedArrowPaint);


    }

    private void onDrawLeftCornerArrow(Canvas canvas, float startX, float startY, float centerX, float centerY, float endX, float endY) {
        mCornerArrowPath.reset();

        mCornerArrowPath.moveTo(startX, startY);
        mCornerArrowPath.lineTo(centerX + mCornerRadius, centerY);

        mCornerArrowPath.quadTo(centerX, centerY, centerX, centerY + mCornerRadius);
        mCornerArrowPath.moveTo(centerX, centerY + mCornerRadius);
        mCornerArrowPath.lineTo(endX, endY);

        mCornerArrowPath.moveTo(endX, endY);
        mCornerArrowPath.lineTo(endX - mArrowLineLength, endY - mArrowLineLength);

        mCornerArrowPath.moveTo(endX, endY);
        mCornerArrowPath.lineTo(endX + mArrowLineLength, endY - mArrowLineLength);

        mCornerArrowPath.close();
        canvas.drawPath(mCornerArrowPath, mDottedArrowPaint);
    }

    /**
     * 绘制直线实心的箭头
     *
     * @param canvas 画布
     * @param startX 箭头起点x坐标
     * @param startY 箭头起点y坐标
     * @param endX   箭头指向位置终点x坐标
     * @param endY   箭头指向位置终点y坐标
     */
    private void onDrawSmritiStarArrow(Canvas canvas, float startX, float startY, float endX, float endY) {
        mVerticalArrowPath.reset();
        mVerticalArrowPath.moveTo(startX, startY);
        mVerticalArrowPath.lineTo(endX, endY);

        mVerticalArrowPath.moveTo(endX, endY);
        mVerticalArrowPath.lineTo(endX - mArrowLineLength, endY - mArrowLineLength);

        mVerticalArrowPath.moveTo(endX, endY);
        mVerticalArrowPath.lineTo(endX + mArrowLineLength, endY - mArrowLineLength);
        mVerticalArrowPath.close();
        canvas.drawPath(mVerticalArrowPath, mArrowPaint);
    }

    private void onDrawSmritiStarName(Canvas canvas, String name, float textX, float textY) {
        canvas.drawText(
                name,
                textX,
                textY,
                mTextPaint);
    }

    private void onDrawSmritiStarIcon(Canvas canvas, SmritiEntity smritiEntity, Rect bounds) {
        //Drawable smrititIconDrawable = mDrawableMap.get(smritiEntity.getResKey());
        Drawable smrititIconDrawable = mDrawableMap.get(smritiEntity);
        if (null != smrititIconDrawable) {
            Log.e(TAG, "onDrawSmritiStarIcon: left:" + bounds.left
                    + ",top:" + bounds.top
                    + ",right" + bounds.right
                    + ",bottom" + bounds.bottom);
            smrititIconDrawable.setBounds(bounds);
            smrititIconDrawable.draw(canvas);
        } else {
            if (mOnDrawableLoadListener != null) {
                mOnDrawableLoadListener.onDrawableLoad(smritiEntity, this);
            }
        }

    }

    /**
     * 得到所有圆点所在的位置
     *
     * @return
     */
    public List<Float> getCircleCenterPointPositionList() {
        return mCircleCenterPointPositionList;
    }

    /**
     * 设置传承数量
     *
     * @param number 传承数量
     */
    private void setSmritiNum(int number) {
        this.mSmritiNum = number;
        //requestLayout();
        invalidate();
    }

    /**
     * 设置线间距的比例系数 set linePadding proportion
     *
     * @param linePaddingProportion
     */
    public void setIndicatorLinePaddingProportion(float linePaddingProportion) {
        this.mLinePadding = linePaddingProportion * defaultStepIndicatorNum;
    }


    /**
     * 设置颜色
     *
     * @param color
     */
    public void setArrowColor(int color) {
        this.mArrowColor = color;
    }

    /**
     * is reverse draw 是否倒序画
     */
    public void reverseDraw(boolean isReverseDraw) {
        this.mIsReverseDraw = isReverseDraw;
        invalidate();
    }

    /**
     * 设置显示的星球
     *
     * @param list 传承星球实体集合
     */
    public void setSmritiEntityList(List<SmritiEntity> list) {
        mCircleCenterPointPositionList.clear();
        mSmritiEntityList.clear();
        mSmritiEntityList.addAll(list);
        //setSmritiNum(mSmritiEntityList.size());
        mSmritiNum = mSmritiEntityList.size();
        onFitSelfPosition();
        requestLayout();
        //invalidate();
        //onResourceReady();
    }

    private int mSelfPosition = -1;

    private void onFitSelfPosition() {
        for (int i = 0; i < mSmritiEntityList.size(); i++) {
            if (mSmritiEntityList.get(i).isSelf()) {
                mSelfPosition = i;
                break;
            }
        }
    }

    private void onResourceReady() {
        if (mOnDrawableLoadListener != null) {
            for (int i = 0; i < mSmritiEntityList.size(); i++) {
                mOnDrawableLoadListener.onDrawableLoad(mSmritiEntityList.get(i), this);
            }
        }
    }

    private float dpToPx(float dp) {
        float scale = getContext().getResources().getDisplayMetrics().density;
        return dp * scale;
    }

    //private final Map<String, Drawable> mDrawableMap = new HashMap<>();
    private final Map<SmritiEntity, Drawable> mDrawableMap = new HashMap<>();


    private OnDrawableLoadListener mOnDrawableLoadListener;

    public void setOnDrawableLoadListener(OnDrawableLoadListener listener) {
        this.mOnDrawableLoadListener = listener;
    }

    @Override
    public void onInvalidate(SmritiEntity entity, Drawable drawable) {
        Log.e(TAG, "onInvalidate: ");
        //onResourceLoaded(entity, drawable);
        mDrawableMap.put(entity, drawable);
        invalidate();
    }

    private float mDownX, mDownY;

    private boolean isDragging = false;

    private final int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();

    private static final int clickTimeout = ViewConfiguration.getTapTimeout();


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getX();
                mDownY = event.getY();
                mDownTime = System.currentTimeMillis();
                return true; // 消费DOWN事件
            case MotionEvent.ACTION_MOVE:
                // 计算移动距离
                float moveX = event.getX() - mDownX;
                float moveY = event.getY() - mDownY;
                // 根据移动距离判断是否为滑动
                if (Math.abs(moveX) > touchSlop || Math.abs(moveY) > touchSlop) {
                    // 已经开始滑动，可以在这里处理滑动逻辑
                    isDragging = true;
                }
                if (isDragging) {
                    // 如果判断为滑动，则消费MOVE事件并返回true，继续处理滑动逻辑
                    //return true;
                    super.onTouchEvent(event);
                }
                break;
            case MotionEvent.ACTION_UP:
                long upTime = System.currentTimeMillis();
                // 判断是否为快速点击，2292，100，clickTimeout=100
                if (!isDragging && upTime - mDownTime < clickTimeout) {
                    // 处理点击事件
                    if (isTouchDrawables(event)) {
                        //performClick();
                        return true;
                    } else {
                        performClick();
                    }
                } else if (isDragging) {
                    // 处理滑动结束的逻辑
                    isDragging = false;
                }
                // 重置状态
                mDownX = mDownY = 0;
                mDownTime = 0;
                return true; // 消费UP事件
            default:
                return super.onTouchEvent(event);


        }

        return super.onTouchEvent(event);
    }

    private boolean isTouchDrawables(@NonNull MotionEvent event) {
        boolean isTouchDrawable = false;
        for (SmritiEntity key : mDrawableMap.keySet()) {
            Drawable drawable = mDrawableMap.get(key);
            if (drawable != null) {
                isTouchDrawable = isTouchOnDrawable(drawable, event);
            }
            if (isTouchDrawable) {
                Log.e(TAG, "isTouchDrawable: " + isTouchDrawable);
                Rect bounds = drawable.getBounds();
                onDrawablePopup(key, bounds);
                return isTouchDrawable;
            }
        }
        Log.e(TAG, "isTouchDrawable: " + isTouchDrawable);
        return isTouchDrawable;
    }

    private void onDrawablePopup(SmritiEntity key, Rect bounds) {
        for (SmritiEntity entity : mSmritiEntityList) {
            //if (Objects.equals(key, entity.getResKey())) {
            if (key == entity) {
                Log.e(TAG, "onDrawablePopup: equals");
                onShowPopupWindow(entity, bounds);
                break;
            } else if (entity.lesserChild() != null
                    //&& Objects.equals(key, entity.lesserChild().getResKey())) {
                    && key == entity.lesserChild()) {
                onShowPopupWindow(entity.lesserChild(), bounds);
                break;
            } else if (entity.lesserParent() != null
                    && key == entity.lesserParent()) {
                onShowPopupWindow(entity.lesserParent(), bounds);
            }
        }
    }

    private boolean isTouchOnDrawable(@NonNull Drawable drawable, @NonNull MotionEvent event) {
        //int[] location = new int[2];
        //view.getLocationOnScreen(location);
        int x = (int) event.getX();
        int y = (int) event.getY();
        Log.e(TAG, "isTouchPointInDrawable: x=" + x + ",y=" + y);
        //int width = drawable.getIntrinsicWidth();
        int width = drawable.getBounds().width();
        int height = drawable.getBounds().height();
        Rect bounds = drawable.getBounds();
        int left = bounds.left;
        int top = bounds.top;
        int right = left + width;
        int bottom = top + height;
        Log.e(TAG, "isTouchOnDrawable: left:" + left
                + ",top:" + top
                + ",right" + right
                + ",bottom" + bottom);
        return x >= left && x < right && y >= top && y < bottom;
    }

    private OnDrawablePopupListener mOnDrawablePopupListener;

    public void setOnDrawablePopupListener(OnDrawablePopupListener listener) {
        this.mOnDrawablePopupListener = listener;
    }

    private void onShowPopupWindow(SmritiEntity entity, Rect bounds) {
        if (entity.isSelf()) {
            return;
        }
        mClickSmritiEntity = entity;
        int x = BasePopup.dpToPx(getContext(), -40);
        if (entity.getNodeType() == SmritiEntity.NODE_LEFT) {
            mBlackBottomPop.showAtAnchorView(this, YGravity.ALIGN_TOP, XGravity.LEFT, x, bounds.centerY());
        } else if (entity.getNodeType() == SmritiEntity.NODE_RIGHT) {
            mBlackBottomPop.showAtAnchorView(this, YGravity.ALIGN_TOP, XGravity.RIGHT, x, bounds.centerY());
        } else if (entity.getNodeType() == SmritiEntity.NODE_LEFT_TOP) {
            mBlackBottomPop.showAtAnchorView(this, YGravity.ALIGN_TOP, XGravity.LEFT, x, bounds.centerY());
        } else {
            mBlackBottomPop.showAtAnchorView(this, YGravity.ALIGN_TOP, XGravity.CENTER, x, bounds.centerY());
        }
    }

    private void initBottomPop() {
        mBlackBottomPop = EasyPopup.create()
                .setContentView(getContext(), R.layout.layout_star_edit_pop)
                .setAnimationStyle(R.style.RightPopAnim)
                .setFocusAndOutsideEnable(true)
                .setOnViewListener((view, popup) -> {
                    view.findViewById(R.id.tvEditComments).setOnClickListener(v -> {
                        if (mOnDrawablePopupListener != null) {
                            mOnDrawablePopupListener.onDrawablePopup(OnDrawablePopupListener.POPUP_EDIT, mClickSmritiEntity);
                        }
                        popup.dismiss();
                    });
                    view.findViewById(R.id.tvUserPage).setOnClickListener(v -> {
                        if (mOnDrawablePopupListener != null) {
                            mOnDrawablePopupListener.onDrawablePopup(OnDrawablePopupListener.POPUP_STAR, mClickSmritiEntity);
                        }
                        popup.dismiss();
                    });
                }).apply();
    }

    private EasyPopup mBlackBottomPop;

    public boolean isScrollToBottom() {
        return scrollToBottom;
    }
}
